package cn.hr.security;

import cn.hr.pojo.SysPermission;
import cn.hr.pojo.SysRole;
import cn.hr.pojo.SysRolePermission;
import cn.hr.pojo.SysUser;
import cn.hr.pojo.SysUserRole;
import cn.hr.service.SysUserService;
import cn.hr.service.impl.SysPermissionService;
import cn.hr.service.impl.SysRolePermissionService;
import cn.hr.service.impl.SysRoleService;
import cn.hr.service.impl.SysUserRoleService;
import org.springframework.security.access.PermissionEvaluator;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * Created by MO on 2018/12/25.
 */
@Service("userDetailsService")
public class SecurityService implements UserDetailsService/*, PermissionEvaluator*/ {
    @Resource
    private SysUserService userService;
    @Resource
    private SysRoleService roleService;
    @Resource
    private SysUserRoleService userRoleService;
    @Resource
    private SysPermissionService permissionService;
    @Resource
    private SysRolePermissionService rolePermissionService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Collection<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
        SysUser user = null;
        try {
            //从数据库取出用户信息
            user = userService.getByCode(username);
            //判断用户是否存在
            if (user == null) {
                throw new UsernameNotFoundException("用户名不存在");
            }
            //添加权限
            List<SysUserRole> userRoles = userRoleService.findByUserId(user.getId());
            for (SysUserRole userRole : userRoles) {
                SysRole role = roleService.findById(userRole.getRoleId());
                authorities.add(new SimpleGrantedAuthority(role.getName()));
            }
            user.setAuthorities(authorities);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return user;
    }

/*    @Override
    public boolean hasPermission(Authentication authentication, Object targetDomainObject, Object permission) {
        //获取loaduserByusername()的结果
        SysUser user = (SysUser) authentication.getPrincipal();
        //获取loaduserByusername中注入的角色
        Collection<GrantedAuthority> authorities = user.getAuthorities();
        //遍历所有角色
        try {
            for (GrantedAuthority authority : authorities) {
                String roleName = authority.getAuthority();
                Integer roleId = roleService.findByName(roleName).getId();
                List<SysRolePermission> permissionList = rolePermissionService.findByRoleId(roleId);
                if (permissionList != null) {
                    //如果拥有所有权限直接返回true
                    if (permissionList.get(0).getPermissionId() == 1) {
                        return true;
                    }
                    //遍历角色的所有权限
                    for (SysRolePermission rolePer : permissionList) {
                        SysPermission sysPer = permissionService.findById(rolePer.getPermissionId());
                        if (targetDomainObject.equals(sysPer.getUrl()) && permission.equals(sysPer.getName())) {
                            return true;
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    @Override
    public boolean hasPermission(Authentication authentication, Serializable targetId, String targetType, Object permission) {
        return false;
    }*/
}
